package com.kxxnzstdsw.utils

import com.kxxnzstdsw.config.Config
import com.zaxxer.hikari.HikariDataSource
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import org.koin.core.context.GlobalContext
import org.springframework.jdbc.datasource.DataSourceUtils
import java.sql.Connection
import java.util.*
import javax.sql.DataSource

fun <T> transaction(dataSource: DataSource? = null, block: suspend (conn: Connection) -> T): T? {
  return try {
    DataSourceUtils.getConnection(dataSource ?: GlobalContext.get().get<HikariDataSource>()).use {
      try {
        it.autoCommit = false
        val res = runBlocking(Dispatchers.IO) { block(it) }
        it.commit()
        res
      } catch (e: Exception) {
        it.rollback()
        throw e
      } finally {
        DataSourceUtils
          .releaseConnection(it, dataSource)
      }
    }
  } catch (e: Exception) {
    throw e
  }
}

fun HikariDataSource.quartzProperties(conf: Config) = Properties().apply {
  setProperty("org.quartz.scheduler.instanceName", conf.quartz.schedulerInstanceName)
  setProperty("org.quartz.scheduler.instanceId", conf.quartz.schedulerInstanceId)
  setProperty("org.quartz.threadPool.class", conf.quartz.threadPoolClass)
  setProperty("org.quartz.threadPool.threadCount", conf.quartz.threadPoolThreadCount.toString())
  setProperty("org.quartz.jobStore.class", conf.quartz.jobStoreClass)
  setProperty("org.quartz.jobStore.driverDelegateClass", conf.quartz.jobStoreDriverDelegateClass)
  setProperty("org.quartz.jobStore.dataSource", this@quartzProperties.poolName)
  setProperty("org.quartz.dataSource.${this@quartzProperties.poolName}.driver", this@quartzProperties.driverClassName)
  setProperty("org.quartz.dataSource.${this@quartzProperties.poolName}.URL", this@quartzProperties.jdbcUrl)
  setProperty("org.quartz.dataSource.${this@quartzProperties.poolName}.user", this@quartzProperties.username)
  setProperty("org.quartz.dataSource.${this@quartzProperties.poolName}.password", this@quartzProperties.password)
}
